home *** CD-ROM | disk | FTP | other *** search
- /*
- * File: CDividedPane.c
- * Module: CDividedPane method definitions
- * System: Mark's Class Library
- * Evironment: MacOS 7.0/THINK C 5.0/TCL 1.1.1
- * Author: Mark Alldritt
- *
- *
- * Copyright © 1992 All Rights Reserved
- * Mark Alldritt
- * 1571 Deep Cove Road
- * N. Vancouver, B.C. CANADA
- *
- *
- * Description:
- *
- * This class implements a pane that is divided either vertically or horizontally. The
- * presentation is similar to that found in Microsoft Word or Microsoft Excel.
- *
- *
- * Edit History:
- *
- * V01-01 Mark Alldritt 15-Jun-1992
- * - Initial version of module.
- *
- */
-
-
- extern RgnHandle gUtilRgn;
-
- #include "CDividedPane.h"
-
-
- #define V_DIVIDER_CURSOR_ID 10000
- #define H_DIVIDER_CURSOR_ID 10001
-
-
- static CursHandle hDividerCursor = NULL,
- vDividerCursor = NULL;
-
-
- void CDividedPane::IDividedPane(CView *anEnclosure, CBureaucrat *aSupervisor,
- short aWidth, short aHeight,
- short aHEncl, short aVEncl,
- SizingOption aHSizing, SizingOption aVSizing,
- Boolean splitHorizontally,
- short dividerPos, short dividerSize,
- short min1st, short min2nd)
-
- /* Override: no
- *
- * Initialize this instance of CDividedPane.
- */
-
- {
- inherited::IPane(anEnclosure, aSupervisor, aWidth, aHeight,
- aHEncl, aVEncl, aHSizing, aVSizing);
- wantsClicks = TRUE;
- visible = TRUE;
- active = TRUE;
-
- /* Set instance variables */
-
- this->min1st = min1st;
- this->min2nd = min2nd;
- this->splitHorizontally = splitHorizontally;
- this->dividerPos = dividerPos;
- this->dividerSize = dividerSize;
-
- /* Build sub-panes */
-
- its1stPane = new(CPane);
- its2ndPane = new(CPane);
-
- if (splitHorizontally)
- {
- its1stPane->IPane(this, this,
- frame.right + 1, dividerPos + 2, -1, -1,
- sizELASTIC, sizFIXEDTOP);
- its2ndPane->IPane(this, this,
- frame.right + 1, frame.bottom - dividerPos - dividerSize + 1,
- -1, dividerPos + dividerSize - 1,
- sizELASTIC, sizELASTIC);
- }
- else
- {
- its1stPane->IPane(this, this,
- dividerPos + 2, frame.bottom + 1, -1, -1,
- sizFIXEDLEFT, sizELASTIC);
- its2ndPane->IPane(this, this,
- frame.right - dividerPos - dividerSize + 1, frame.bottom + 1,
- dividerPos + dividerSize - 1, -1,
- sizELASTIC, sizELASTIC);
- }
- its1stPane->wantsClicks = its2ndPane->wantsClicks = TRUE;
-
- /* Load cursor resources as required */
-
- if (splitHorizontally)
- {
- if (!vDividerCursor)
- FailNILRes(vDividerCursor = GetCursor(V_DIVIDER_CURSOR_ID));
- }
- else
- if (!hDividerCursor)
- FailNILRes(hDividerCursor = GetCursor(H_DIVIDER_CURSOR_ID));
- }
-
-
- void CDividedPane::Draw(Rect *area)
-
- /* Override: yes
- *
- * Draw the divider.
- */
-
- {
- Rect r;
-
- LongToQDRect(&frame, &r);
- if (splitHorizontally)
- {
- r.top = dividerPos;
- r.bottom = r.top + dividerSize;
- r.left--;
- r.right++;
- }
- else
- {
- r.left = dividerPos;
- r.right = r.left + dividerSize;
- r.top--;
- r.bottom++;
- }
-
- PenPat(black);
- FrameRect(&r);
- }
-
-
- void CDividedPane::DoClick(Point hitPt, short modifierKeys, long when)
-
- /* Override: yes
- *
- * Handle a mouse click. If the user has clicked within the divider then we allow the
- * user to move the divider around. When the mouse is released, resize the sub-panes
- * as appripriate and redraw everything.
- */
-
- {
- Rect r;
-
- LongToQDRect(&frame, &r);
- if (splitHorizontally)
- {
- r.top = dividerPos;
- r.bottom = r.top + dividerSize;
- r.left--;
- r.right++;
- }
- else
- {
- r.left = dividerPos;
- r.right = r.left + dividerSize;
- r.top--;
- r.bottom++;
- }
-
- if (PtInRect(hitPt, &r))
- {
- long result;
- Rect frameR;
- Rect slopR;
-
- RectRgn(gUtilRgn, &r);
- LongToQDRect(&frame, &frameR);
- slopR = frameR;
- if (splitHorizontally)
- {
- frameR.top += min1st;
- frameR.bottom -= min2nd;
- }
- else
- {
- frameR.left += min1st;
- frameR.right -= min2nd;
- }
- result = DragGrayRgn(gUtilRgn, hitPt, &frameR, &slopR,
- splitHorizontally ? vAxisOnly : hAxisOnly, NULL);
-
- if (result != 0x80008000)
- {
- Rect delta1st,
- delta2nd;
-
- InvalRect(&r);
- if (splitHorizontally)
- {
- if (HiWord(result) == 0)
- return;
- dividerPos += HiWord(result);
- r.top += HiWord(result);
- r.bottom += HiWord(result);
-
- /* Build delta rectangles for the following ChangeSize calls. */
-
- delta1st.top = delta1st.left = delta1st.right = 0;
- delta1st.bottom = HiWord(result);
- delta2nd.left = delta2nd.right = delta2nd.top = 0;
- delta2nd.bottom = -HiWord(result);
- }
- else
- {
- if (LoWord(result) == 0)
- return;
- dividerPos += LoWord(result);
- r.left += LoWord(result);
- r.right += LoWord(result);
-
- /* Build delta rectangles for the following ChangeSize calls. */
-
- delta1st.top = delta1st.left = delta1st.bottom = 0;
- delta1st.right = LoWord(result);
- delta2nd.top = delta2nd.left = delta2nd.bottom = 0;
- delta2nd.right = -LoWord(result);
- }
-
- its1stPane->ChangeSize(&delta1st, its1stPane->autoRefresh);
- if (splitHorizontally)
- its2ndPane->Offset(0, HiWord(result), FALSE);
- else
- its2ndPane->Offset(LoWord(result), 0, FALSE);
- its2ndPane->ChangeSize(&delta2nd, its2ndPane->autoRefresh);
- Refresh();
- }
- }
- }
-
-
- void CDividedPane::AdjustCursor(Point where, RgnHandle mouseRgn)
-
- /* Override: yes
- *
- * Whenever the mouse passes over the divider change the cursor to an up/down arrow or
- * a left/arrow, depending on the type of pane division.
- */
-
- {
- Rect dividerR,
- r;
- Rect aperture;
- LongRect lr;
- LongPt lp;
- Point mousePos;
-
- mousePos = where;
- WindToFrame(mousePos, &lp);
- LongToQDPt(&lp, &mousePos);
-
- LongToQDRect(&frame, &aperture);
- LongToQDRect(&frame, ÷rR);
- if (splitHorizontally)
- {
- dividerR.top = dividerPos;
- dividerR.bottom = dividerR.top + dividerSize;
- dividerR.left--;
- dividerR.right++;
- }
- else
- {
- dividerR.left = dividerPos;
- dividerR.right = dividerR.left + dividerSize;
- dividerR.top--;
- dividerR.bottom++;
- }
-
- if (PtInRect(mousePos, ÷rR))
- {
- SetCursor(splitHorizontally ? *vDividerCursor : *hDividerCursor);
-
- RectRgn(gUtilRgn, ÷rR);
- FrameToGlobalR(&frame, &r);
- OffsetRgn(gUtilRgn, dividerR.left - r.left, dividerR.top - r.top);
- SectRgn(mouseRgn, gUtilRgn, mouseRgn);
- }
- else
- {
- RgnHandle dividerRgn;
-
- inherited::AdjustCursor(where, mouseRgn);
-
- dividerRgn = NewRgn();
- RectRgn(dividerRgn, ÷rR);
- RectRgn(gUtilRgn, &aperture);
- DiffRgn(gUtilRgn, dividerRgn, gUtilRgn);
- DisposeRgn(dividerRgn);
-
- FrameToGlobalR(&lr, &r);
- OffsetRgn(gUtilRgn, aperture.left - r.left, aperture.top - r.top);
- SectRgn(mouseRgn, gUtilRgn, mouseRgn);
- }
- }
-
-
- short CDividedPane::GetDividerPos()
-
- /* Override: no
- *
- * Return the current position of the divider.
- */
-
- {
- return (dividerPos);
- }
-
-
- CPane *CDividedPane::Get1stPane()
-
- /* Override: no
- *
- * Return the handle of the top or left pane within the divided pane.
- */
-
- {
- return (its1stPane);
- }
-
-
- CPane *CDividedPane::Get2ndPane()
-
- /* Override: no
- *
- * Return the handle of the bottom or right pane within the divided pane.
- */
-
- {
- return (its2ndPane);
- }